/**
 * @Author: CimZzz
 * @Date: 2022-01-06 18:19:03
 * 
 * RTSP 库头文件
 * 定义 RTSP 服务器操作方法
 */

#ifndef _VL_RTSP__H_
#define _VL_RTSP__H_

#include "defs.h"
#include "media_session.h"
#include "rtsp_context.h"
#include "rtsp_connection.h"
#include "utils/queue_thread.h"
#include "utils/tcpserver.h"
#include "utils/sync_code.h"


namespace VLRTSP {

/**
 * @Author: CimZzz
 * @Date: 2022-01-13 15:13:59
 * 
 * RTSP 指令
 */
struct RTSPCommand;

/**
 * @Author: CimZzz
 * @Date: 2022-01-06 18:21:29
 * 
 * RTSP 服务器
 */
class RTSPServer {
public:

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-10 19:39:08
	 * 
	 * RTSP 服务器状态
	 */
	enum RTSPServerStatus {
		/**
		 * @Author: CimZzz
		 * @Date: 2022-01-10 19:39:38
		 * 
		 * 停止状态
		 */
		Stopped,

		/**
		 * @Author: CimZzz
		 * @Date: 2022-01-10 19:43:30
		 * 
		 * 失败状态，等同于 [Stopped] 状态，额外表示因为异常导致服务器停止
		 */
		Error,

		/**
		 * @Author: CimZzz
		 * @Date: 2022-01-10 19:40:28
		 * 
		 * 启动中状态
		 */
		Bootsrap,

		/**
		 * @Author: CimZzz
		 * @Date: 2022-01-10 19:39:47
		 * 
		 * 已启动状态
		 */
		Running,


		/**
		 * @Author: CimZzz
		 * @Date: 2022-01-10 19:40:00
		 * 
		 * 已销毁状态
		 */
		Destroyed,
	};

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-10 19:38:01
	 * 
	 * RTSP 服务器状态回调函数
	 * @param RTSPServerStatus RTSP 服务器状态枚举
	 * @param std::string 状态描述字符串，根据不同的服务器状态有不同的含义
	 * - Stopped   : 该状态下值为空
	 * - Error     : 该状态下值为错误描述消息
	 * - Bootsrap  : 该状态下值为空
	 * - Running   : 该状态下值为服务器链接
	 * - Destroyed : 该状态下值为空
	 */
	using StatusCallback = std::function<void(RTSPServerStatus, std::shared_ptr<std::string>)>;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-07 10:22:07
	 * 
	 * 显示构造器
	 * @param port 监听端口
	 * @param statusCallback 状态回调函数
	 */
	explicit RTSPServer(uint16_t port, StatusCallback statusCallback);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-11 10:44:02
	 * 
	 * 析构函数
	 */
	~RTSPServer();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-10 19:48:50
	 * 
	 * 添加新的媒体会话
	 * @param session 媒体会话指针
	 */
	void addMediaSession(MediaSession* session);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-14 19:08:21
	 * 
	 * 推送媒体资源数据
	 * @param sessionId 媒体会话 Id
	 * @param sourceId 资源 Id
	 * @param data 媒体资源数据
	 */
	void pushMediaData(const std::string& sessionId, uint32_t sourceId, MediaSourceData* data);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-07 10:23:21
	 * 
	 * 启动 RTSP 服务器
	 */
	void start();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-07 10:24:24
	 * 
	 * 关闭 RTSP 服务器
	 */
	void destroy();

private:
	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-13 14:54:58
	 * 
	 * RTSP 指令执行回调
	 */
	using CommandCallback = std::function<void()>;

	/**
	 * +======================================================================================================================+
	 * @Author: CimZzz
	 * @Date: 2022-01-11 11:06:30
	 * 
	 * 代码分割块，以下内容涉及: 
	 * 
	 * 内部方法
	 * 
	 */

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-13 10:57:10
	 * 
	 * TCP 服务器启动回调函数
	 */
	void _onServerStart();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-13 10:57:23
	 * 
	 * TCP 服务器结束回调函数
	 */
	void _onServerDone();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-13 10:57:46
	 * 
	 * 接收到 Socket 回调函数
	 */
	void _onRecvSocket(std::shared_ptr<TCPSocket>& socket);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-13 14:55:50
	 * 
	 * 接收到 RTSP 消息队列指令
	 * @param command RTSP 指令
	 */
	void _onRecvCommand(std::shared_ptr<RTSPCommand>& command);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-11 11:07:37
	 * 
	 * 切换当前 RTSP 服务器状态
	 * @param status 服务器状态
	 * @param message 状态消息
	 */
	void _changeStatus(RTSPServerStatus status, std::string* message = nullptr);

	/**
	 * +======================================================================================================================+
	 * @Author: CimZzz
	 * @Date: 2022-01-11 11:32:11
	 * 
	 * 代码分割块，以下内容涉及: 
	 * 
	 * 成员变量
	 * 
	 */

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-12 14:49:08
	 * 
	 * 端口号
	 */
	uint32_t port;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-10 19:45:00
	 * 
	 * RTSP 服务器状态回调函数
	 */
	StatusCallback statusCallback;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-11 10:46:08
	 * 
	 * RTSP 服务器状态
	 */
	RTSPServerStatus status;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-10 19:45:39
	 * 
	 * 线程锁
	 */
	std::recursive_mutex mutex;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-10 19:46:24
	 * 
	 * TCP 服务器
	 */
	TCPServer tcpServer;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-13 11:40:44
	 * 
	 * 链接同步码（发号机）
	 */
	SyncCode syncCode;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-13 10:53:18
	 * 
	 * RTSP 上下文
	 */
	RTSPContext context;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-13 14:53:42
	 * 
	 * RTSP 指令消息队列
	 */
	QueueThread<RTSPCommand> commandThread;
};

}


#endif //_VL_RTSP__H_
